#ifdef WIIMOTE

#include "inc\GUI\wiimote\wiimotestatusdialog.h"
#include "inc/GUI/wiimote/wiimotewidget.h"

#include <QShowEvent>;

#ifdef KINECT
#include "GUI/kinect/kinectdialog.h"
#endif

#include "ui_wiimotestatusdialog.h"

WiimoteStatusDialog::WiimoteStatusDialog(qWiimote* wiimote, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::WiimoteStatusDialog),
    oldX(-1),
    oldY(-1),
    _wiimote(wiimote)
{
    ui->setupUi(this);
    _labels.insert(qWiimote::A, ui->aLabel);
    _labels.insert(qWiimote::B, ui->bLabel);
    _labels.insert(qWiimote::Minus, ui->minusLabel);
    _labels.insert(qWiimote::Home, ui->homeLabel);
    _labels.insert(qWiimote::Plus, ui->plusLabel);
    _labels.insert(qWiimote::One, ui->oneLabel);
    _labels.insert(qWiimote::Two, ui->twoLabel);
    _labels.insert(qWiimote::Up, ui->upLabel);
    _labels.insert(qWiimote::Down, ui->downLabel);
    _labels.insert(qWiimote::Left, ui->leftLabel);
    _labels.insert(qWiimote::Right, ui->rightLabel);

    _signals.insert(qWiimote::A, SIGNAL(aPress()));
    _signals.insert(qWiimote::B, SIGNAL(bPress()));
    _signals.insert(qWiimote::Minus, SIGNAL(minusPress()));
    _signals.insert(qWiimote::Home, SIGNAL(homePress()));
    _signals.insert(qWiimote::Plus, SIGNAL(plusPress()));
    _signals.insert(qWiimote::One, SIGNAL(onePress()));
    _signals.insert(qWiimote::Two, SIGNAL(twoPress()));
    _signals.insert(qWiimote::Up, SIGNAL(upPress()));
    _signals.insert(qWiimote::Down, SIGNAL(downPress()));
    _signals.insert(qWiimote::Left, SIGNAL(leftPress()));
    _signals.insert(qWiimote::Right, SIGNAL(rightPress()));

    foreach (qWiimote::Button button, _signals.keys()) {
        connect(_wiimote, _signals.find(button).value(), this, SLOT(negativeFeedback()));
    }

    connect(_wiimote, SIGNAL(buttonPress(qWiimote::Button)), this, SLOT(recordButton(qWiimote::Button)));

    setWindowFlags(Qt::Tool); // | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint

    if (_wiimote != NULL) {
        connect(_wiimote, SIGNAL(batteryChanged(float)), this, SLOT(updateBattery(float)));
        updateBattery(_wiimote->getBattery());
    }
}

WiimoteStatusDialog::~WiimoteStatusDialog()
{
    delete ui;
}

QWidget* WiimoteStatusDialog::associate(QWidget *dialog) {
    QWidget* ret = parentWidget();
    WiimoteWidget* wiiReset = dynamic_cast<WiimoteWidget*>(ret);
    if (wiiReset != NULL) {
        wiiReset->setWiimote(NULL);
    }
    setParent(dialog, Qt::Tool);
    clearCommands();
    WiimoteWidget* associate = dynamic_cast<WiimoteWidget*>(dialog);
    if (associate != NULL) {
        associate->setWiimote(this);
    }
    if (_wiimote->isConnected()) {
        show();
    }
    return ret;
}

qWiimote* WiimoteStatusDialog::getWiimote() {
    return _wiimote;
}

void WiimoteStatusDialog::setCommand(qWiimote::Button button, QString command, const QObject *receiver, const char *member) {
    if (_labels.contains(button)) {
        _labels.find(button).value()->setText(command);
    }
    if (_signals.contains(button)) {
        disconnect(_wiimote, _signals.find(button).value(), this, SLOT(negativeFeedback()));
        connect(_wiimote, _signals.find(button).value(), this, SLOT(positiveFeedback()));
        connect(_wiimote, _signals.find(button).value(), receiver, member);
        _activeConnections.insert(button, QPair<const QObject*, const char*>(receiver, member));
    }
}

void WiimoteStatusDialog::linkPositiveFeedback(const QObject *sender, const char *signal) {
    connect(sender, signal, this, SLOT(positiveFeedback()));
    _positiveFeedback.append(QPair<const QObject*, const char*>(sender, signal));
}

void WiimoteStatusDialog::linkNegativeFeedback(const QObject *sender, const char *signal) {
    connect(sender, signal, this, SLOT(negativeFeedback()));
    _negativeFeedback.append(QPair<const QObject*, const char*>(sender, signal));
}

void WiimoteStatusDialog::clearCommands() {
    foreach (QLabel* label, _labels.values()) {
        label->setText("-");
    }
    foreach (qWiimote::Button button, _activeConnections.keys()) {
        QPair<const QObject*, const char*> pair = _activeConnections.find(button).value();
        disconnect(_wiimote, _signals.find(button).value(), pair.first, pair.second);
        disconnect(_wiimote, _signals.find(button).value(), this, SLOT(positiveFeedback()));
        connect(_wiimote, _signals.find(button).value(), this, SLOT(negativeFeedback()));
        _activeConnections.remove(button);
    }
    typedef QPair<const QObject*, const char*> SignalPair;
    foreach (SignalPair item, _positiveFeedback) {
        disconnect(item.first, item.second, this, SLOT(positiveFeedback()));
    }
    _positiveFeedback.clear();
    foreach (SignalPair item, _negativeFeedback) {
        disconnect(item.first, item.second, this, SLOT(negativeFeedback()));
    }
    _negativeFeedback.clear();
}

void WiimoteStatusDialog::updateBattery(float percent) {
    ui->batteryBar->setValue(qRound(percent * 100));
}

void WiimoteStatusDialog::positiveFeedback() {
    _wiimote->rumble(150);
}

void WiimoteStatusDialog::negativeFeedback() {
    _wiimote->rumble(500);
}

void WiimoteStatusDialog::showEvent(QShowEvent *event) {
    if (oldX != -1 && oldY != -1) {
        move(oldX, oldY);
    } else if (parentWidget() != NULL) {
        move(parentWidget()->x() - frameGeometry().width(), parentWidget()->y());
    }
}

void WiimoteStatusDialog::recordButton(qWiimote::Button button) {
    QLabel* label = _labels.find(button).value();
    if (label != NULL && label->text() != "-") {
        QLog::log(QString("Wiimote press: ") + qWiimote::getButtonName(button) + QString(" (") + label->text() + QString(")"));
        //qDebug() << "Wiimote press:" << label->text() << ("(" + qWiimote::getButtonName(button) + ")");
    } else {
        QLog::log(QString("Wiimote press: ") + qWiimote::getButtonName(button) + QString(" (No command linked)"));
        //qDebug() << "Wiimote press:" << "No command linked" << ("(" + qWiimote::getButtonName(button) + ")");
    }
}

void WiimoteStatusDialog::hideEvent(QHideEvent *event) {
    oldX = x();
    oldY = y();
}

#endif
